import axios, { AxiosInstance } from "axios"
import stringify from 'qs/lib/stringify'
import docCookies from "./cookies"
import { ElMessage } from "element-plus"
import { API_BASE } from "./consts"

type ReqError = Error & { data: any, statusCode: number }

const onReject = ({ statusCode, info, data }, showMsg = true) => {
  info = info || '发生未知异常'
  showMsg && ElMessage.error(info)
  const error = new Error() as ReqError
  error.data = data
  error.statusCode = statusCode
  error.message = info
  return Promise.reject(error)
}

const getFilename = (content: string) => {
  const arr = decodeURIComponent(content)
    .toLowerCase()
    .split(';')
    .pop()
    .split('=')

  return (arr[arr.indexOf('filename') + 1] || '').split('/').pop()
}

export const createAxiosInstance = (isForm?: boolean, baseURL = API_BASE) => {
  const instance = axios.create()

  instance.defaults.baseURL = baseURL
  instance.defaults.withCredentials = true

  if (isForm) {
    instance.defaults.transformRequest = [_ => stringify(_)]
  }

  instance.interceptors.request.use(
    config => {
      const token = docCookies.getItem('user-center-sso-token')
      if (token) {
        config.headers['Authorization'] = `Bearer ${token}`
      } if (!token) {
        window.parent.postMessage({ event: "nologin", msg: "未登录" }, '*')
      }
      return config
    }
  )

  instance.interceptors.response.use(
    res => {
      const { data, headers } = res
      if (res.status === 401 || data.code === 401) {
        window.parent.postMessage({ event: "nologin", msg: "未登录" }, '*')
        return onReject({ statusCode: res.status, info: data.msg, data })
      }
      if (data instanceof Blob) {
        (data as any).name = getFilename(headers['content-disposition'])
      }
      if ([200, undefined].includes(data.code)) {
        return data
      }
      return onReject({ statusCode: res.status, info: data.msg, data })
    },
    e => {
      const res = e.response
      const { data = {}, status } = res || {}
      const info = res ? (data.errorInfo || e.message) : '请求失败，请稍后重试'
      return onReject({ statusCode: status, info, data })
    }
  )

  return instance
}

export const request = createAxiosInstance()

const formRequest = createAxiosInstance(true)

export const post: AxiosInstance['post'] = (...args) => formRequest.post(...args)
